package org.faster.dal.descriptor;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.faster.dal.criteria.Model;
import org.faster.dal.criteria.QueryCriteria;

public class Table implements Serializable {
    
    /**
     * 
     */
    private static final long serialVersionUID = -1767385529269117048L;
    
    
    /**
     * 所有字段-字符串
     */
    private String columns;
    
    
    /**
     * 表名
     */
    private String tableName;
    
    /**
     * 字段列表
     */
    private Map<String, Column> fields;
    
    /**
     * 主键
     */
    private PrimaryKey primaryKey;
    
    
    /**
     * 查询条件
     */
    private final ThreadLocal<QueryCriteria> queryCriteriaLocal = new ThreadLocal<QueryCriteria>();
    
    /**
     * 条件参数封装
     */
    private final ThreadLocal<LinkedHashMap<String,Object>> conditionsLocal = new ThreadLocal<LinkedHashMap<String,Object>>();
    
    /**
     * 更新参数封装
     */
    private final ThreadLocal<LinkedHashMap<String,Object>> paramsLocal = new ThreadLocal<LinkedHashMap<String,Object>>();
    
    
    public Table() {
        super();
        fields = new HashMap<String, Column>();
        primaryKey = new PrimaryKey();
    }
    

    /**
     * 处理后的表字段 {@code String} 格式的字符串
     * <ul>
     * <li>对字段时行排序处理，sql也会进行排序；</li>
     * <li>最高级别隐藏不需要显示的字段；</li>
     * <li>生成主键相关信息；</li>
     * <li>生成外键相关信息；</li>
     * <li>生成自定义显示信息；</li>
     * </ul>
     * @param fields 原始字段列表，可为null,null时计算当时实列信息
     * @return 处理后的表字段 {@code String} 格式的字符串。
     * @since 1.0
     */
    public String caculationAllColumn(){
        if(StringUtils.isNotEmpty(columns)){
            return columns;
        }else{
            StringBuffer sb = new StringBuffer();
            List<Column> fds = new ArrayList<Column>();
            if(fds == null || fds.size() == 0){
                fds.addAll(this.fields.values());
            }
            for(Column f:fds){
                sb.append(f.getFieldName()).append(",");
            }
            if(sb.length() > 0){
                columns = sb.deleteCharAt(sb.lastIndexOf(",")).toString();
            }
        }
        return columns;
    }
   
    public String getTableName() {
        return tableName;
    }
    public void setTableName(String tableName) {
        this.tableName = tableName;
    }
    
    public Map<String, Column> getFields() {
        return fields;
    }
    
    public Column getField(String fieldName) {
        return fields.get(fieldName);
    }

    public void setFields(Map<String, Column> fields) {
        this.fields = fields;
    }

    public PrimaryKey getPrimaryKey() {
        return primaryKey;
    }
    
    public void addPrimaryFieldName(String fieldName){
        primaryKey.addFieldName(fieldName);
    }
    
    public void addField(Column field){
        this.fields.put(field.getFieldName(), field);
    }

    public QueryCriteria getQueryCriteria() {
        return queryCriteriaLocal.get();
    }

    public void setQueryCriteria(QueryCriteria queryCriteria) {
        this.queryCriteriaLocal.set(queryCriteria);
    }
    
    public LinkedHashMap<String, Object> getConditions() {
        return conditionsLocal.get();
    }

    public LinkedHashMap<String, Object> getParams() {
        return paramsLocal.get();
    }
    
    public void setConditions(LinkedHashMap<String, Object> condition) {
        conditionsLocal.set(condition);
    }

    public void setParams(LinkedHashMap<String, Object> params) {
        LinkedHashMap<String, Object> tmpParams = new LinkedHashMap<String, Object>();
        Iterator<String> keys = params.keySet().iterator();
        while(keys.hasNext()){
            String key = keys.next();
            if(Model.MODEL_NAME.equals(key) || Model.MODEL_ID.equals(key)){
                continue;
            }else{
                tmpParams.put(key, params.get(key));
            }
        }
        paramsLocal.set(tmpParams);
    }

    public void putCondition(String key, Object value){
        if(conditionsLocal.get() == null){
            conditionsLocal.set(new LinkedHashMap<String, Object>());
        }
        this.conditionsLocal.get().put(key, value);
    }
    
    public void putParams(String key, Object value){
        if(paramsLocal.get() == null){
            paramsLocal.set(new LinkedHashMap<String, Object>());
        }
        this.paramsLocal.get().put(key, value);
    }
    
    public void resetQueryCriteria(){
        this.queryCriteriaLocal.set(new QueryCriteria());
    }
    
    public void resetQueryConditions(){
        conditionsLocal.set(new LinkedHashMap<String, Object>());
    }
    
    public void resetQueryParams(){
        paramsLocal.set(new LinkedHashMap<String, Object>());
    }

    public String getColumns() {
        return columns;
    }


    


    
    

}
